// created by noellynch
// May 14, 2011

package com.gruntdb.engines.indexedjson;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


import com.gruntdb.core.GruntDataStore;
import com.gruntdb.objects.GruntDBIndexStore;

public class IndexedJSONStorageProperties {
	public static final String CURRENT_INDEX_INSERT_OFFSET = "CURRENT_INDEX_INSERT_OFFSET";

	public static final String CURRENT_INDEX = "CURRENT_INDEX";

	public static final String SEGMENT_START = "SEGMENT_ST_";
	public static final String SEGMENT_END = "SEGMENT_END_";

	private		ScheduledExecutorService		EXECUTOR = Executors.newScheduledThreadPool(1);

	private		File				mcl_propsFile;
	private		Properties			mcl_properties;
	private		SaveProperties		mcl_saver = new SaveProperties();

	private		IndexedJSONStorageEngine		mcl_dataStore;

	public	IndexedJSONStorageProperties(IndexedJSONStorageEngine cl_store) {
		mcl_dataStore = cl_store;
	}

	protected	void	loadDataStoreProperties() {
		mcl_propsFile = new File(mcl_dataStore.getLocation(), mcl_dataStore.getFileReferenceName() + ".properties");
		mcl_properties = new Properties();
		if(!mcl_propsFile.exists()) {
			// create a new properties file
			try {
				mcl_propsFile.createNewFile();
				mcl_properties.put(CURRENT_INDEX, "" + 0);
				mcl_properties.put(CURRENT_INDEX_INSERT_OFFSET, "" + 0);
				flushProperties();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} else {
			try {
				mcl_properties.load(new FileReader(mcl_propsFile));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		EXECUTOR.scheduleAtFixedRate(mcl_saver, 5, 5, TimeUnit.SECONDS);
	}

	public	long	getLong(String str_property) {
		return Long.parseLong(mcl_properties.get(str_property).toString());
	}

	public	void	close() {
		flushProperties();
		EXECUTOR.shutdownNow();
	}

	private	void	flushProperties() {
		synchronized (mcl_properties) {
			GruntDBIndexStore			lcl_idx = mcl_dataStore.getIndexStore();
			if(lcl_idx.isDirty()) {
				mcl_properties.put(CURRENT_INDEX, "" + lcl_idx.getCurrentID());
				//mcl_properties.put(CURRENT_INDEX_INSERT_OFFSET, "" + lcl_idx.getCurrentIndexInsertOffset());
			}

			IndexedJSONStoreManager		lcl_segMgr = mcl_dataStore.getSegmentManager();
			if(lcl_segMgr.isDirty()) {
				int		li_n = lcl_segMgr.getNumSegments();
				for(int li_temp = 0; li_temp < li_n; li_temp++) {
					IndexedJSONSegmentFile		lcl_f = lcl_segMgr.getSegmentAt(li_temp);
					mcl_properties.put(SEGMENT_START + lcl_f.getFileIndex(), "" + lcl_f.getLowerIndex());
					mcl_properties.put(SEGMENT_END + lcl_f.getFileIndex(), "" + lcl_f.getUpperIndex());
				}
			}
			
			if(lcl_idx.isDirty() || (lcl_segMgr.isDirty())) {
				try {
					System.out.println("saving properties");
					FileWriter		lcl_out = new FileWriter(mcl_propsFile);
					mcl_properties.store(lcl_out, "");
					lcl_out.flush();
					lcl_out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			lcl_idx.clearDirty();
			lcl_segMgr.clearDirty();
		}
	}

	class	SaveProperties implements Runnable {
		@Override
		public void run() {
			flushProperties();
		}
	}
}
